package com.creditease.cn.monitor.dao.redis;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

public enum RedisClient {
	JEDISPOOLINSTANCE;
	// private JedisPool jedisPools;// 连接池
	private ShardedJedisPool shardedJedisPools;// 切片连接池
	
	private Logger LOGGER = LoggerFactory.getLogger(RedisClient.class);

	// 只会初始化一次
	RedisClient() {
		// initialPool();
		try {
			initialShardedPool();
			LOGGER.info("***************************************Redis连接初始化完成***************************************");
		} catch (Exception e) {
			LOGGER.info("***************************************Redis连接初始化异常***************************************"
					+ e.getMessage());
		}
	}

	/**
	 * 初始化非切片池
	 */
	// private void initialPool() {
	// // 池基本配置
	// JedisPoolConfig config = new JedisPoolConfig();
	// // 控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取；
	// // 如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
	// config.setMaxTotal(20);
	// config.setMaxIdle(5);
	// config.setMaxWaitMillis(1000l);
	// config.setTestOnBorrow(false);
	//
	// jedisPools = new JedisPool(config, "127.0.0.1", 6379);
	// }

	/**
	 * 初始化切片池
	 */
	private void initialShardedPool() throws Exception {
		String resource = "nsmonitor-redis.properties";
		long start = System.currentTimeMillis();
		InputStream in = null;
		ClassLoader loader = JedisPoolFactory.class.getClassLoader();
		if (loader != null) {
			in = loader.getResourceAsStream("nsmonitor-redis.properties");
		}
		if (in == null) {
			in = ClassLoader.getSystemResourceAsStream(resource);
		}
		if (in == null) {
			throw new Exception("Could not find resource file: ".concat(resource));
		}
		Properties properties = new Properties();
		try {
			properties.load(in);
			in.close();
		} catch (IOException e) {
			throw new Exception("Could not load resource file: ".concat(resource), e);
		}
		int maxTotal = Integer.parseInt(properties.getProperty("maxTotal"));
		int maxIdle = Integer.parseInt(properties.getProperty("maxIdle"));
		int minIdle = Integer.parseInt(properties.getProperty("minIdle"));
		int maxActive = Integer.parseInt(properties.getProperty("maxActive"));
//		int maxWaitMillis = Integer.parseInt(properties.getProperty("redis.jedisPool.maxWaitMillis"));
//		boolean testOnBorrow = Boolean.parseBoolean(properties.getProperty("redis.jedisPool.testOnBorrow"));
		String host = properties.getProperty("host");
		int port = Integer.parseInt(properties.getProperty("port", "6379"));
		Integer timeout = Integer.parseInt(properties.getProperty("timeout"));

		//校验参数合法化
		String arg = "redis init error.host[" + host + "]port[" + port + "]minIdle[" + minIdle + "]maxIdle[" + maxIdle
				+ "]maxActive[" + maxActive + "]";
		if ((host == null) || host.equals("") || (port <= 0) || (timeout < 0) || (minIdle < 0) || (maxIdle < 0)
				|| (maxActive < 0)) {
			throw new IllegalArgumentException(arg);
		}
		if ((minIdle > maxIdle) || (maxIdle > maxActive)) {
			throw new IllegalArgumentException(arg);
		}
		
		// 池基本配置
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(maxTotal);
		config.setMinIdle(minIdle);
		config.setMaxIdle(maxIdle);
//		config.setMaxWaitMillis(maxWaitMillis);
//		config.setTestOnBorrow(testOnBorrow);
		// slave链接
		List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
		shards.add(new JedisShardInfo(host, port, timeout));
		// shards.add(new JedisShardInfo("127.0.0.1", 6379, "master"));

		// 构造池
		shardedJedisPools = new ShardedJedisPool(config, shards);
		long end = System.currentTimeMillis();
		LOGGER.info("构造redis连接池耗时：" + (end - start) + "毫秒");
	}

	/**
	 * 
	 * @return 非切片额客户端连接（不推荐）
	 */
	// public Jedis getJedisInstance() {
	// Jedis jedis = jedisPools.getResource();
	// return jedis;
	// }

	/**
	 * 
	 * @return 切片额客户端连接（推荐）
	 */
	public ShardedJedis getShardedJedisInstance() throws Exception {
		long start = System.currentTimeMillis();
		ShardedJedis shardedJedis = shardedJedisPools.getResource();
		long end = System.currentTimeMillis();
		LOGGER.info("Redis连接时间：" + (end - start) + "毫秒");
		return shardedJedis;
	}

	public static void main(String[] args) {
		long end = 0;
		long start = System.currentTimeMillis();
		try {
			ShardedJedis shardedJedis = JEDISPOOLINSTANCE.getShardedJedisInstance();
			shardedJedis.get("111");
			end = System.currentTimeMillis();
			System.out.println("Redis查询时间：" + (end - start) + "毫秒");
		} catch (Exception e) {
			end = System.currentTimeMillis();
			System.out.println("Redis查询时间：" + (end - start) + "毫秒");
			e.printStackTrace();
		}
	}

	public ShardedJedisPool getShardedJedisPools() {
		return shardedJedisPools;
	}

	public void setShardedJedisPools(ShardedJedisPool shardedJedisPools) {
		this.shardedJedisPools = shardedJedisPools;
	}

}